home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / ip / trace / tcpdump-2.2.1 / pcap-nit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-02  |  4.5 KB  |  190 lines

  1. /*
  2.  * Copyright (c) 1988, 1990 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that: (1) source code distributions
  7.  * retain the above copyright notice and this paragraph in its entirety, (2)
  8.  * distributions including binary code include the above copyright notice and
  9.  * this paragraph in its entirety in the documentation or other materials
  10.  * provided with the distribution, and (3) all advertising materials mentioning
  11.  * features or use of this software display the following acknowledgement:
  12.  * ``This product includes software developed by the University of California,
  13.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14.  * the University nor the names of its contributors may be used to endorse
  15.  * or promote products derived from this software without specific prior
  16.  * written permission.
  17.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20.  */
  21. #ifndef lint
  22. static  char rcsid[] =
  23.     "@(#)$Header: pcap-nit.c,v 1.14 92/06/02 17:57:34 mccanne Exp $ (LBL)";
  24. #endif
  25.  
  26. #include <stdio.h>
  27. #include <netdb.h>
  28. #include <ctype.h>
  29. #include <signal.h>
  30. #include <errno.h>
  31. #include <sys/types.h>
  32. #include <sys/time.h>
  33. #include <sys/timeb.h>
  34. #include <sys/socket.h>
  35. #include <sys/file.h>
  36. #include <sys/ioctl.h>
  37. #include <net/nit.h>
  38.  
  39. #include <net/if.h>
  40. #include <netinet/in.h>
  41. #include <netinet/in_systm.h>
  42. #include <netinet/ip.h>
  43. #include <netinet/if_ether.h>
  44. #include <netinet/ip_var.h>
  45. #include <netinet/udp.h>
  46. #include <netinet/udp_var.h>
  47. #include <netinet/tcp.h>
  48. #include <netinet/tcpip.h>
  49. #include <net/bpf.h>
  50.  
  51. #include "interface.h"
  52.  
  53. /*
  54.  * The chunk size for NIT.  This is the amount of buffering
  55.  * done for read calls.
  56.  */
  57. #define CHUNKSIZE (2*1024)
  58.  
  59. /*
  60.  * The total buffer space used by NIT.
  61.  */
  62. #define BUFSPACE (4*CHUNKSIZE)
  63.  
  64. void
  65. readloop(cnt, if_fd, fp, printit)
  66.     int cnt;
  67.     int if_fd;
  68.     struct bpf_program *fp;
  69.     void (*printit)();
  70. {
  71.     u_char buf[CHUNKSIZE];
  72.     struct bpf_insn *fcode;
  73.     int cc;
  74.  
  75.     fcode = fp->bf_insns;
  76.  
  77.     while ((cc = read(if_fd, (char *)buf, sizeof(buf))) > 0) {
  78.         register u_char *bp, *bstop;
  79.         register u_char *sp;
  80.         register struct nit_hdr *nh;
  81.         register int datalen = 0;
  82.         int caplen;
  83.         
  84.         /*
  85.          * Loop through each packet.  The increment expression
  86.          * rounds up to the next int boundary past the end of
  87.          * the previous packet.
  88.          */
  89.         bstop = buf + cc;
  90.         for (bp = buf; bp < bstop;
  91.              bp += ((sizeof(struct nit_hdr)+datalen+sizeof(int)-1)
  92.                 & ~(sizeof(int)-1))) {
  93.  
  94.             nh = (struct nit_hdr *)bp;
  95.             sp = bp + sizeof(*nh);
  96.             
  97.             switch (nh->nh_state) {
  98.             case NIT_CATCH:
  99.                 datalen = nh->nh_datalen;
  100.                 break;
  101.             case NIT_SEQNO:
  102.             case NIT_NOMBUF:
  103.             case NIT_NOCLUSTER:
  104.             case NIT_NOSPACE:
  105.                 datalen = 0;
  106.                 continue;
  107.             default:
  108.                 (void)fprintf(stderr,
  109.                     "tcpdump: bad nit state %d\n",
  110.                     nh->nh_state);
  111.                 exit(1);
  112.             }
  113.             caplen = nh->nh_wirelen;
  114.             if (caplen > snaplen)
  115.                 caplen = snaplen;
  116.             if (bpf_filter(fcode, sp, nh->nh_wirelen, caplen)) {
  117.                 if (cnt >= 0 && --cnt < 0) {
  118.                     wrapup(if_fd);
  119.                     return;
  120.                 }
  121.                 (*printit)(sp, &nh->nh_timestamp, 
  122.                        nh->nh_wirelen, caplen);
  123.             }
  124.         }
  125.     }
  126.     perror("tcpdump: read");
  127.     exit(-1);
  128. }
  129.  
  130. wrapup(fd)
  131.     int fd;
  132. {
  133.     close(fd);
  134. }
  135.  
  136. int
  137. initdevice(device, pflag, linktype)
  138.     char *device;
  139.     int pflag;
  140.     int *linktype;
  141. {
  142.     struct sockaddr_nit snit;
  143.     struct nit_ioc nioc;
  144.     int if_fd;
  145.  
  146.     if (snaplen < 96) 
  147.         /*
  148.          * NIT requires a snapshot length of at least 96.
  149.          */
  150.         snaplen = 96;
  151.  
  152.     if_fd = socket(AF_NIT, SOCK_RAW, NITPROTO_RAW);
  153.  
  154.     if (if_fd < 0) {
  155.         perror("tcpdump: socket");
  156.         exit(-1);
  157.     }
  158.  
  159.     snit.snit_family = AF_NIT;
  160.     (void)strncpy(snit.snit_ifname, device, NITIFSIZ);
  161.  
  162.     if (bind(if_fd, (struct sockaddr *)&snit, sizeof(snit))) {
  163.         (void) fprintf(stderr, "tcpdump: bind: ");
  164.         perror(snit.snit_ifname);
  165.         exit(1);
  166.     }
  167.  
  168.     bzero((char *)&nioc, sizeof(nioc));
  169.     nioc.nioc_bufspace = BUFSPACE;
  170.     nioc.nioc_chunksize = CHUNKSIZE;
  171.     nioc.nioc_typetomatch = NT_ALLTYPES;
  172.     nioc.nioc_snaplen = snaplen;
  173.     nioc.nioc_bufalign = sizeof(int);
  174.     nioc.nioc_bufoffset = 0;
  175.     nioc.nioc_flags = pflag ? NF_TIMEOUT : NF_PROMISC|NF_TIMEOUT;
  176.     nioc.nioc_timeout.tv_sec = 1;
  177.     nioc.nioc_timeout.tv_usec = 0;
  178.  
  179.     if (ioctl(if_fd, SIOCSNIT, &nioc) != 0) {
  180.         perror("tcpdump: SIOCSNIT");
  181.         exit(1);
  182.     }
  183.     /*
  184.      * NIT supports only ethernets.
  185.      */
  186.     *linktype = DLT_EN10MB;
  187.  
  188.     return if_fd;
  189. }
  190.